package graphicUserInterface.mainInterface.screenDrawing;

import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.media.CannotRealizeException;
import javax.media.Manager;
import javax.media.NoPlayerException;
import javax.media.Player;
import javax.media.protocol.DataSource;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

import engine.HINBsEngineThread;
import engine.events.HINBEventListener;
import engine.events.NewCoordEvent;
import engine.exceptions.NoWebcamFoundException;
import engine.motionDetection.EngineMotionDetectionInterface;
import engine.videoCapture.ConfigureWebcam;

public class CalibrationScreenDrawer {
	/* *********************************************************
	 * InnerClasses
	 * Summary : 
	 * 		- 
	 * ********************************************************* */
	private static class ChangeScreenAction implements ActionListener{

		protected String _screenLbl;
		protected CardLayout _consernedLayout;
		protected JPanel _consernedContainer;
		public ChangeScreenAction(String screenLabel,
				JPanel container) {
			_screenLbl = screenLabel;
			_consernedContainer = container;
			LayoutManager cLayout = container.getLayout();
			if (cLayout instanceof CardLayout) {
				_consernedLayout = (CardLayout)cLayout;
			}else{
				_consernedLayout = null;
				throw new IllegalArgumentException("the given " +
						"container don't use a CardLayout");
			}
		}

		@Override
		public void actionPerformed(ActionEvent arg0) {
			_consernedLayout.show(_consernedContainer, _screenLbl);
			_consernedContainer.validate();
		}
		
	}
	private static class ChangeAndDrawScreenAction 
							extends ChangeScreenAction{

		public ChangeAndDrawScreenAction(String screenLabel, JPanel container) {
			super(screenLabel, container);
			
		}
		
	}
	private static class StartMotionDetectionAction
							implements ActionListener{
		
		@Override
		public void actionPerformed(ActionEvent arg0) {
			webCamVisualisation.add(webCamPlayer.getVisualComponent());
			webCamVisualisation.add(trackingPanel);
			
			motionDetection.startMotionDetection();
		}
		
	}

	private static class NewCoordListener implements HINBEventListener{
		
		private JPanel _movPanel;
		
		public NewCoordListener(JPanel movingPanel){
			_movPanel = movingPanel;
		}
		@Override
		public void handleNewEvent(NewCoordEvent evt) {
			_movPanel.setLocation(evt.getX()-2, evt.getY()-2);
		}
		
	}
	/* *********************************************************
	 * End of InnerClasses
	 * ********************************************************* */

	/* *********************************************************
	 * Attributes
	 * ********************************************************* */
	private static String fstScreenLabel = "fst";
	private static String sndScreenLabel = "snd";
	private static Player webCamPlayer;
	private static JPanel trackingPanel;
	private static JPanel webCamVisualisation;
	private static EngineMotionDetectionInterface motionDetection;
	/* *********************************************************
	 * Static Methods
	 * ********************************************************* */
	public static JPanel build(){
		System.out.println("GUI:CalibrationScreenDrawer build");
		JPanel calibrationScr = new JPanel();
		draw(calibrationScr);
		System.out.println("GUI:CalibrationScreenDrawer  build over");
		return calibrationScr;
	}
	public static void draw(JPanel container){
		System.out.println("GUI:CalibrationScreenDrawer draw");
		//First clean container
		container.removeAll();
		//set the new Layout
		CardLayout containerLayout = new CardLayout();
		container.setLayout(containerLayout);
		JPanel fstPart = new JPanel();
		container.add(fstPart, fstScreenLabel);
		drawFstPart(fstPart);
		JPanel sndPart = buildSndPart(container);
		container.add(sndPart, sndScreenLabel);
		
	}
	
	private static JPanel  drawFstPart(JPanel fstScreen) {
		System.out.println("GUI:CalibrationScreenDrawer buildFstPart");
		
		fstScreen.setLayout(new GridLayout(1, 2));
		fstScreen.setSize(800, 550);
		//creation of the webCamPlayer ...
		//NOTE : the ConfigureWebCam.doCon...Webcam should not be 
		// called in a asynchrone way --> the datasources is needed after...
		
		DataSource source;
		try {
			source = ConfigureWebcam.doConfigureWebcam();
			webCamPlayer = null;
			webCamPlayer = Manager.createRealizedPlayer(source);
		} catch (NoWebcamFoundException e1) {
			e1.printStackTrace();
		} catch (NoPlayerException e) {
			e.printStackTrace();
		} catch (CannotRealizeException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			if(webCamPlayer == null){
				fstScreen.add(new JLabel("webCam don't work ... Fan !"));
			}else{
				webCamPlayer.start();
				JPanel webCamPanel = new JPanel();
				webCamPanel.add(webCamPlayer.getVisualComponent());
				fstScreen.add(webCamPanel);
				fstScreen.validate();
			}
		}
		
		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(
				new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
		rightPanel.add(
				new JLabel(
						new ImageIcon("./assets/images/position.png")
						)
				);
		JButton nextScreen = new JButton("next step");
		
		nextScreen.addActionListener(
				new ChangeAndDrawScreenAction(sndScreenLabel, (JPanel) fstScreen.getParent()));
		nextScreen.addActionListener(new StartMotionDetectionAction());
		rightPanel.add(nextScreen);
		fstScreen.add(rightPanel);
		System.out.println("GUI:CalibrationScreenDrawer buildFstPart over !");
		return fstScreen;
	}
	
	/**
	 * create a JPanel and draw the second part of the screen 
	 * @param container
	 * @return
	 */
	private static JPanel buildSndPart(JPanel container) {
		System.out.println("GUI:CalibrationScreenDrawer  buildSndPart");
		JPanel screen = new JPanel();
		screen.setLayout(new GridLayout(1,2));
		//prepare the tracking
		trackingPanel = registerForTracking(webCamPlayer);
		webCamVisualisation = new JPanel();
		webCamVisualisation.setLayout(null);
		screen.add(webCamVisualisation);
		JPanel rightPanel = new JPanel();
		rightPanel.setLayout(new GridLayout(2,1));
		rightPanel.add(new JLabel("put the filtred image here"));
		JPanel bottomRightPanel = new JPanel();
		bottomRightPanel.setLayout(
				new BoxLayout(bottomRightPanel, BoxLayout.PAGE_AXIS));
		JPanel bottomButtonsPanel = new JPanel();
		bottomButtonsPanel.setLayout(new GridLayout(1,2));
		bottomButtonsPanel.setSize(400, 50);
		JButton prevScreen = new JButton("previous step");
		prevScreen.addActionListener(
				new ChangeScreenAction(fstScreenLabel, container));
		//TODO prevScreen.addActionListener(new stopcurrentCalibration(...));
		bottomButtonsPanel.add(prevScreen);
		JButton startGame = new JButton("let's play NOW !!!");
		startGame.setEnabled(false);
		bottomButtonsPanel.add(startGame);
		bottomRightPanel.add(bottomButtonsPanel);
		rightPanel.add(bottomRightPanel);
		screen.add(rightPanel);
		System.out.println("GUI:CalibrationScreenDrawer buildSndPart over !");
		return screen;
	}
	private static JPanel registerForTracking(Player ply) {
		System.out.println("GUI:CalibrationScreenDrawer  registerForTracking");
		JPanel movingSquare = new JPanel();
		movingSquare.setBackground(Color.RED);
		movingSquare.setSize(4, 4);
		movingSquare.setLocation(-10, -10);
		//first initialize the motionDetection
		HINBEventListener listener =  new NewCoordListener(movingSquare);
		motionDetection = HINBsEngineThread.getInstance().createAndLauchMotionDetection(ply,listener);
		return movingSquare;
	}
}
